#include <stdio.h>
#include <stdlib.h>
#include "list.h"

int dll_insert_by_location(dlink *list, int loc, int data){
    if(loc < 1){
        printf("invalied location\n");
        return -1;
    }

    dllnode *new = (dllnode *)malloc(sizeof(dllnode));
    if(new == NULL) {
        perror("malloc");
        return -1;
    }
    if(loc == 1){
        new->data = data;
        new->prior = NULL;
        new->next = *list;
        if(*list != NULL){
            (*list)->prior = new;
        }
        *list = new;

        return 0;
    }

    dllnode *target = *list;
    int i = 0;
    while(target != NULL && i < loc -2){
        target = target->next;
        i++;
    }
    if(target == NULL){
        printf("invlaid location %d\n",loc);
        free(new);
        return -1;
    }

    new->data = data;
    new->next = target->next;
    new->prior = target;
    if(target->next != NULL){
        target->next->prior = new;
    }
    target->next = new;

    return 0;
}

int dll_delete_by_location(dlink *list, int loc){
    if(loc < 1 || *list == NULL){
        printf("invalid locaton or list empty\n");
        return -1;
    }
    
    dllnode *target = *list;
    if(loc == 1){
        *list = target->next;
        if(target->next != NULL){
            target->next->prior = NULL;
        }
        free(target);
        return 0;
    }


    int i = 0;
    while(target != NULL && i < loc - 2){
        target = target->next;
        i++;
    }

    if(target == NULL || target->next == NULL){
        printf("nothing to delete\n");
        return -1;
    }

    dllnode *delete = target->next;
    target->next = delete->next;
    if(target->next != NULL){
        target->next->prior = target;
    }
    free(delete);

    return 0;
}

dllnode *dll_find_node_by_location(dlink *list, int loc){
    if(loc < 1 || *list == NULL){
        printf("invalid loctaion or empty list\n");
        return NULL;
    }

    int i = 0;
    dllnode *target = *list;
    while (target != NULL && i < loc -1){
        target = target->next;
        i++;
    }

    if(target == NULL){
        printf("no node %d in list\n", loc);
        return NULL;
    }

    return target;
}

dllnode *dll_find_node_by_data(dlink *list, int data, int *loc){
    if(*list == NULL){
        printf("list is empty\n");
        return NULL;
    }

    dllnode *target = *list;
    int i = 1;
    while(target != NULL){
        if(target->data == data)
            break;
        target = target->next;
        i++;
    }

    if(target == NULL){
        printf("no sllnode with data %d\n",data);
        return NULL;
    }

    *loc = i;
    
    return target; 
}

int dll_length_of_list(dlink *list){
    if(*list == NULL)
        return 0;

    dllnode *target = *list;
    int i = 0;
    while(target != NULL){
        target = target->next;
        i++;
    }

    return i;
}